package com.tsfyun.scm.service.impl.system;

import com.tsfyun.common.base.config.OrikaBeanMapper;
import com.tsfyun.common.base.dto.FileDTO;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.system.SubjectOverseasDTO;
import com.tsfyun.scm.dto.system.SubjectOverseasPlusDTO;
import com.tsfyun.scm.dto.system.SubjectOverseasQTO;
import com.tsfyun.scm.entity.customer.Customer;
import com.tsfyun.scm.entity.customer.Supplier;
import com.tsfyun.scm.entity.system.SubjectOverseas;
import com.tsfyun.scm.mapper.system.SubjectOverseasMapper;
import com.tsfyun.scm.service.file.IUploadFileService;
import com.tsfyun.scm.service.system.ISubjectOverseasBankService;
import com.tsfyun.scm.service.system.ISubjectOverseasService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.service.system.ISubjectService;
import com.tsfyun.scm.vo.system.SubjectOverseasBankVO;
import com.tsfyun.scm.vo.system.SubjectOverseasPlusVO;
import com.tsfyun.scm.vo.system.SubjectOverseasVO;
import com.tsfyun.scm.vo.system.SubjectVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.WeekendSqls;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 *
 * @since 2020-03-19
 */
@Service
public class SubjectOverseasServiceImpl extends ServiceImpl<SubjectOverseas> implements ISubjectOverseasService {

    @Autowired
    private SubjectOverseasMapper subjectOverseasMapper;
    @Autowired
    private OrikaBeanMapper beanMapper;
    @Autowired
    private ISubjectService subjectService;
    @Autowired
    private ISubjectOverseasBankService subjectOverseasBankService;
    @Autowired
    private IUploadFileService uploadFileService;

    @Override
    public List<SubjectOverseasVO> findList(SubjectOverseasQTO qto) {
        return subjectOverseasMapper.findList(qto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addPlus(SubjectOverseasPlusDTO dto) {
        SubjectOverseasDTO overseas = dto.getOverseas();
        //保存境外公司
        Long subjectOverseasId = add(overseas);
        //保存境外公司银行
        subjectOverseasBankService.addBatch(subjectOverseasId,dto.getBanks());
        return subjectOverseasId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editPlus(SubjectOverseasPlusDTO dto) {
        SubjectOverseasDTO overseas = dto.getOverseas();
        //保存境外公司
        edit(overseas);
        //删除境外公司银行
        subjectOverseasBankService.removeByOverseasId(overseas.getId());
        //保存境外公司银行
        subjectOverseasBankService.addBatch(overseas.getId(),dto.getBanks());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long add(SubjectOverseasDTO dto) {
        SubjectOverseas overseas = new SubjectOverseas();
        //获取主体公司信息
        SubjectVO subjectVO = subjectService.findByCode();
        TsfPreconditions.checkArgument(Objects.nonNull(subjectVO),new ServiceException("主体公司未找到"));
        overseas.setSubjectId(subjectVO.getId());
        overseas.setName(StringUtils.removeSpecialSymbol(dto.getName()));
        overseas.setNameCn(StringUtils.removeSpecialSymbol(dto.getNameCn()));
        overseas.setTel(StringUtils.removeSpecialSymbol(dto.getTel()));
        overseas.setFax(StringUtils.removeSpecialSymbol(dto.getFax()));
        overseas.setAddress(StringUtils.removeSpecialSymbol(dto.getAddress()));
        overseas.setAddressCn(StringUtils.removeSpecialSymbol(dto.getAddressCn()));
        overseas.setChapter(StringUtils.removeSpecialSymbol(dto.getChapter()));
        overseas.setIsDefault(Objects.equals(dto.getIsDefault(),true));
        overseas.setDisabled(Boolean.FALSE);
        try{
            //本条数据默认将其他数据设置非默认
            if(overseas.getIsDefault()){
                SubjectOverseas update = new SubjectOverseas();
                update.setIsDefault(Boolean.FALSE);
                subjectOverseasMapper.updateByExampleSelective(update, Example.builder(SubjectOverseas.class).where(
                        WeekendSqls.<SubjectOverseas>custom().andEqualTo(SubjectOverseas::getSubjectId,overseas.getSubjectId())
                ).build());
            }
            super.saveNonNull(overseas);

            //关联文件信息
            if(StringUtils.isNotEmpty(dto.getFileId())){
                FileDTO fileDTO = new FileDTO();
                fileDTO.setDocId(dto.getFileId());
                fileDTO.setDocType("subject_overseas");
                uploadFileService.relateFile(overseas.getId().toString(),fileDTO);
            }
        } catch ( DuplicateKeyException e) {
            if(e.getMessage().contains("UK_subject_overseas_name")) {
                throw new ServiceException("英文名称已经存在");
            } else {
                throw new ServiceException("保存失败，请检查数据是否填写正确");
            }
        }
        return overseas.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SubjectOverseasDTO dto) {
        SubjectOverseas overseas = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(overseas),new ServiceException("境外公司信息不存在"));

        overseas.setName(StringUtils.removeSpecialSymbol(dto.getName()));
        overseas.setNameCn(StringUtils.removeSpecialSymbol(dto.getNameCn()));
        overseas.setTel(StringUtils.removeSpecialSymbol(dto.getTel()));
        overseas.setFax(StringUtils.removeSpecialSymbol(dto.getFax()));
        overseas.setAddress(StringUtils.removeSpecialSymbol(dto.getAddress()));
        overseas.setAddressCn(StringUtils.removeSpecialSymbol(dto.getAddressCn()));
        overseas.setChapter(StringUtils.removeSpecialSymbol(dto.getChapter()));
        overseas.setIsDefault(Objects.equals(dto.getIsDefault(),true));

        try{
            //本条数据默认将其他数据设置非默认
            if(overseas.getIsDefault()){
                SubjectOverseas update = new SubjectOverseas();
                update.setIsDefault(Boolean.FALSE);
                subjectOverseasMapper.updateByExampleSelective(update, Example.builder(SubjectOverseas.class).where(
                        WeekendSqls.<SubjectOverseas>custom().andEqualTo(SubjectOverseas::getSubjectId,overseas.getSubjectId())
                        .andNotEqualTo(SubjectOverseas::getId,overseas.getId())
                ).build());
            }
            super.updateById(overseas);
        } catch ( DuplicateKeyException e) {
            if(e.getMessage().contains("UK_subject_overseas_name")) {
                throw new ServiceException("英文名称已经存在");
            } else {
                throw new ServiceException("保存失败，请检查数据是否填写正确");
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDisabled(Long id, Boolean disabled) {
        SubjectOverseas overseas = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(overseas),new ServiceException("境外公司信息不存在"));
        SubjectOverseas update = new SubjectOverseas();
        update.setDisabled(disabled);
        subjectOverseasMapper.updateByExampleSelective(update, Example.builder(Supplier.class).where(
                WeekendSqls.<SubjectOverseas>custom().andEqualTo(SubjectOverseas::getId,id)
        ).build());
    }

    @Override
    public void remove(Long id) {
        SubjectOverseas overseas = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(overseas),new ServiceException("境外公司信息不存在"));
        //查看是否存银行信息
        int count = subjectOverseasBankService.countByOverseasId(id);
        TsfPreconditions.checkArgument(count < 1,new ServiceException(String.format("该境外公司下面存在%d条银行信息，不允许删除",count)));
        try{
            super.removeById(id);
        } catch (DataIntegrityViolationException e) {
            throw new ServiceException("当前境外公司存在关联性数据，不允许删除");
        }
    }

    @Override
    public SubjectOverseasPlusVO detailPlus(Long id) {
        SubjectOverseas overseas = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(overseas),new ServiceException("境外公司信息不存在"));
        SubjectOverseasPlusVO plusVO = new SubjectOverseasPlusVO();
        plusVO.setOverseas(beanMapper.map(overseas,SubjectOverseasVO.class));
        List<SubjectOverseasBankVO> overseasBankVOS = subjectOverseasBankService.listByOverseasId(overseas.getId());
        plusVO.setBanks(overseasBankVOS);
        return plusVO;
    }

    @Override
    public SubjectOverseasVO defOverseas() {
        return subjectOverseasMapper.defOverseas();
    }
}
